home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
DOCS
/
GNU
/
TEXI2STR
/
texi2strng.pl
< prev
Wrap
Perl Script
|
1995-07-02
|
21KB
|
877 lines
#!/usr/local/bin/perl
# texi2strong v1.0 - © 1995 Jochen Scharrlach (jscharrl@ba-stuttgart.de)
# This program is freeware, i.e. you can freely use and distribute it.
# You may not sell this program or distribute modified versions without
# having the permission from the author.
# Usage: texi2strng <texinfo-file> <directory>
$RiscOS = 1;
$dirSep = "." if $RiscOS;
$dirSep = "/" if ! $RiscOS;
$protectedChars = '\*\/_#<>';
$refQuote = '<>=-';
$O = "\000"; # {
$C = "\001"; # }
$; = "\002";
$B = "\003"; # \
$A = "\004"; # @
%Commands = ("set", \&ComSet,
"clear", \&ComClear,
"ifclear", \&ComIfClear,
"ifset", \&ComIfSet,
"enumerate", \&ComEnumerate,
"itemize", \&ComItemize,
"item", \&ComItem,
"itemx", \&ComItem,
"end", \&ComEnd,
"example", \&ComExample,
"smallexample", \&ComExample,
"lisp", \&ComExample,
"smalllisp", \&ComExample,
"ignore", \&ComIgnore,
"titlepage", \&ComIgnore,
"tex", \&ComIgnore,
"shorttitlepage", \&DummyProc,
"c", \&DummyProc,
"comment", \&DummyProc,
"cindex", \&ComIndex,
"findex", \&ComIndex,
"vindex", \&ComIndex,
"kindex", \&ComIndex,
"pindex", \&ComIndex,
"tindex", \&ComIndex,
"iftex", \&ComIfTex,
"ifinfo", \&ComIfInfo,
"node", \&ComNode,
"bye", \&ComNode, # write the last Node!
"page", \&ComPage,
"center", \&ComCentre,
"include", \&ComInclude,
"menu", \&ComMenu,
"synindex", \&ComSynindex,
"syncodeindex", \&ComSynindex,
"table", \&ComTable,
"vtable", \&ComTable,
"ftable", \&ComTable,
"printindex", \&ComPrintindex,
"display", \&ComDisplay,
"format", \&ComDisplay,
"flushleft", \&ComFlushleft,
"flushright", \&ComFlushright,
"quotation", \&ComQuotation,
"sp", \&ComSpace,
"deftypefn", \&ComDeftypefn,
"deftypefun", \&ComDeftypefun,
"deftypevar", \&ComDeftypevar,
"defop", \&ComDefop,
#headings:
"chapter" => \&ComOneline,
"section" => \&ComOneline,
"subsection" => \&ComOneline,
"subsubsection" => \&ComOneline,
"top" => \&ComOneline,
"unnumbered" => \&ComOneline,
"unnumberedsec" => \&ComOneline,
"unnumberedsubsec" => \&ComOneline,
"unnumberedsubsubsec" => \&ComOneline,
"appendix" => \&ComOneline,
"appendixsec" => \&ComOneline,
"appendixsubsec" => \&ComOneline,
"appendixsubsubsec" => \&ComOneline,
"majorheading" => \&ComOneline,
"chapheading" => \&ComOneline,
"heading" => \&ComOneline,
"subheading" => \&ComOneline,
"subsubheading" => \&ComOneline,
#those should really be ignored:
"contents", \&DummyProc,
"shortcontents", \&DummyProc,
"summarycontents", \&DummyProc,
"everyheading", \&DummyProc,
"everyfooting", \&DummyProc,
"evenheading", \&DummyProc,
"evenfooting", \&DummyProc,
"oddheading", \&DummyProc,
"oddfooting", \&DummyProc,
"heading", \&DummyProc,
"footing", \&DummyProc,
"footnotestyle", \&DummyProc,
"cartouche", \&DummyProc,
"settitle", \&DummyProc,
"setfilename", \&DummyProc,
"smallbook", \&DummyProc,
"group", \&DummyProc,
"finalout", \&DummyProc,
"setchapternewpage", \&DummyProc,
"need", \&DummyProc,
#not implemented (yet):
"exdent", \&DummyProc,
"paragraphindent", \&DummyProc,
"vskip", \&DummyProc,
"noindent", \&DummyProc,
"defindex", \&WarnProc,
"defcodeindex", \&WarnProc,
"defcv", \&DummyProc,
"deffn", \&DummyProc,
"deffnx", \&DummyProc,
"defindex", \&DummyProc,
"defivar", \&DummyProc,
"defmac", \&DummyProc,
"defmethod", \&DummyProc,
"defopt", \&DummyProc,
"defspec", \&DummyProc,
"deftp", \&DummyProc,
"deftypevr", \&DummyProc,
"defvr", \&DummyProc);
@ifs = ("ifclear", "ifset", "iftex", "ifinfo");
%Oneline = ("chapter" => "{fH2}",
"section" => "{fH3}",
"subsection" => "{fH4}",
"subsubsection" => "{fH5}",
"top" => "{fH1}",
"unnumbered" => "{fH2}",
"unnumberedsec" => "{fH3}",
"unnumberedsubsec" => "{fH4}",
"unnumberedsubsubsec" => "{fH5}",
"appendix" => "{fH2}",
"appendixsec" => "{fH3}",
"appendixsubsec" => "{fH4}",
"appendixsubsubsec" => "{fH5}",
"majorheading" => "{fH1}",
"chapheading" => "{fH2}",
"heading" => "{fH3}",
"subheading" => "{fH4}",
"subsubheading" => "{fH5}");
%Prefix = ("code" => $O."fCode".$C,
"kbd" => $O."fCode".$C,
"key" => $O."fCode".$C,
"samp" => $O."fEmphasis".$C,
"var" => $O."fStrong".$C,
"file" => $O."fCite".$C,
"dfn" => $O."fUnderline".$C,
"cite" => $O."fCite".$C,
"emph" => $O."fEmphasis".$C,
"strong" => $O."fStrong".$C,
"quotation" => $O."fCite".$C,
"sc" => "-");
%Postfix = ("code" => $O."f".$C,
"kbd" => $O."f".$C,
"key" => $O."f".$C,
"samp" => $O."f".$C,
"var" => $O."f".$C,
"file" => $O."f".$C,
"dfn" => $O."f".$C,
"cite" => $O."f".$C,
"emph" => $O."f".$C,
"strong" => $O."f".$C,
"quotation" => $O."f".$C,
"sc" => "-");
%Special = ("copyright" => "©",
"bullet" => "•",
"dots" => "…",
"w" => "—",
"minus" => "-",
"result" => "=\>",
"expansion" => "\<=\>",
"print" => "»",
"error" => "ERROR",
"equiv" => "==",
"point" => "-\>",
"TeX" => "TeX",
"code" => 1,
"kbd" => 1,
"key" => 1,
"samp" => 1,
"var" => 1,
"file" => 1,
"dfn" => 1,
"cite" => 1,
"emph" => 1,
"strong" => 1,
"quotation" => 1,
"dfn" => 1);
%unknownCommands =
("i" => 1,
"b" => 1,
"t" => 1,
"r" => 1,
"w" => 1,
"dmn" => 1);
%unknownChars =
("refill" => 1,
"i" => 1,
"b" => 1,
"t" => 1,
"r" => 1,
"w" => 1,
"dmn" => 1,
"asis" => 1);
%switches = ();
$currentFile = "";
%File2Node = ("!Root" => "Top");
%Node2File = ("Top" => "!Root",
"top" => "!Root");
%Node2Menu = ();
@ThisNode = ();
$ConceptIndex = {};
$FunctionIndex = {};
$VariableIndex = {};
$KeystrokeIndex = {};
$ProgramIndex = {};
$DatatypeIndex = {};
%IndexCommands =
("cindex" => \$ConceptIndex,
"findex" => \$FunctionIndex,
"vindex" => \$VariableIndex,
"kindex" => \$KeystrokeIndex,
"pindex" => \$ProgramIndex,
"tindex" => \$DatatypeIndex );
%IndexRefs =
("cp" => \$ConceptIndex,
"fn" => \$FunctionIndex,
"vr" => \$VariableIndex,
"ky" => \$KeystrokeIndex,
"pg" => \$ProgramIndex,
"tp" => \$DatatypeIndex );
$MenuFlag = 0;
$ifCounter = 0;
$ignoreIfCounter = 0;
$ignoreIt = 1;
@Dokument = ();
$unknown = 0;
$numberedList = 1;
$normalList = 2;
$tableList = 3;
@listStack = ();
$listType = $unknown;
$listItemPrefix = 0;
# ****** Das Hauptprogramm:
print "Compile $ARGV[0]...\n";
# open (OUT, ">$ARGV[1]/!Root") || die "Couldn't open output!\n";
# $currentFile = "!Root";
compileFile($ARGV[0]);
close OUT;
# ****** Subroutinen:
sub compileFile {
local($file) = @_;
# local(FILE);
local($cmd, $args, $line, $stat, $block, $_, $1, $2, $3, $node);
$stat = 0;
open (HANDLE, $file) || die "Can't open $file!\n";
# warn "File $file opened!\n";
@Dokument = <HANDLE>;
close HANDLE;
do {
$block = "";
while (($line = shift(@Dokument)) && !($MenuFlag && $line =~ /^\*/) &&
(! ($line =~ /^@(\w+)\b/ && $Commands{$1})))
{
$block .= $line;
}
if (!$ignoreIfCounter)
{
&output(&translate($block));
}
if ($line =~ /^@(\w+)\s*(.*)\s*$/ && $Commands{$1})
{
$cmd = $1;
$args = $2;
$args =~ s/(\S)\s+$/$1/;
if ($ignoreIfCounter)
{
$ignoreIfCounter++ if (grep(/^$cmd$/, @ifs));
$ignoreIfCounter-- if ($cmd eq "end" && grep(/^$args$/, @ifs));
}
elsif ($Commands{$cmd} == \&ComIgnore)
{
while (($line = shift(@Dokument)) &&
!($line =~ /^\@end $cmd/ ))
{ }
}
else
{
# $args = translate($args) if $cmd ne "c";
&{$Commands{$cmd}}($cmd, translate($args)) if $Commands{$cmd} && ($cmd ne "c");
}
}
elsif ($MenuFlag && $line =~ /^\* ([^:]+)::(.*)/)
{
$cmd = translate($1);
$args = translate($2);
output(MakeRef($cmd,Ref2File($cmd)).":".$args."\n");
$Node2Menu{$cmd} = $currentNode;
}
elsif ($MenuFlag && $line =~ /^\* ([^:]+):\s*(\S[^\.]*)\.(.*)/)
{
$cmd = translate($1);
$node = translate($2);
$args = translate($3);
output(MakeRef($cmd,Ref2File($node)).":".$args."\n");
$Node2Menu{$node} = $currentNode;
}
} while ($_ = @Dokument);
}
sub translate {
local($_) = @_;
local($1, $2);
s/\@\@/$A/g;
s/\\/$B/g;
s/\@c .*$//g;
s/\@comment .*$//g;
# s/\\([$quoteChars])/$;$1/g;
s/\@{/$;$O/g;
s/\@}/$;$C/g;
s/\@://g;
s/\@\././g;
s/([$protectedChars])/$;$1/g;
s/\@$;\*\n/\n# (line break)\n/g;
s/\@$;\*/\n# (line break)\n/g;
while (s/\@(\w+){([^{}]*)}/&ComAttribute($1, $2)/eg)
{ };
s/@(\w+)\b/&ComSpecial($1)/eg; #
return rebuild($_);
}
sub rebuild {
local ($_) = @_;
s/$A/\@/g;
s/$B/\\\\/g;
s/$;/\\/g;
s/$O/\{/g;
s/$C/\}/g;
return $_;
}
sub ComSet {
local($cmd, $args) = @_;
if ($args =~ /^(\w+)\s+(.*)$/)
{
$switches{$1} = $2;
}
else
{
$switches{$args} = 1;
}
}
sub ComClear {
local($cmd, $args) = @_;
$switches{$args} = 0;
}
sub ComQuotation {
local($cmd, $args);
output("#fCite\n");
}
sub ComAttribute {
local($cmd, $args) = @_;
return ComSpecial($cmd, $args) if $args eq "";
return uc($args) if $cmd eq "sc";
return $switches{$args} if $cmd eq "value";
return ComFootnote($args) if $cmd eq "footnote";
return ComXRef($cmd, $args) if $cmd eq "ref" || $cmd eq "xref" ||
$cmd eq "pxref" || $cmd eq "inforef";
if (!$Prefix{$cmd} && !$unknownCommands{$cmd})
{
$unknownCommands{$cmd} = 1;
warn "Command $cmd unknown!\n";
}
return $Prefix{$cmd}.$args.$Postfix{$cmd};
}
sub ComFootnote {
local ($text) = @_;
$noOfFootnotes++;
push (@Footnotes, "($noOfFootnotes) ".translate($text)."\n\n");
return "{fEmphasis}($noOfFootnotes){f}";
}
sub ComSpecial {
local($cmd) = @_;
if (!$Special{$cmd} && !$unknownChars{$cmd})
{
$unknownChars{$cmd} = 1;
warn "Special character $cmd unknown!";
warn " next line: $Dokument[0]";
}
if ($Special{$cmd} == 1)
{
return $Prefix{$cmd};
}
else
{
return $Special{$cmd};
}
}
sub ComIfSet {
local($cmd, $args) = @_;
if ($switches{$args})
{
$ifCounter++;
}
else
{
$ignoreIfCounter++;
}
}
sub ComIfClear {
local($cmd, $args) = @_;
if (!$switches{$args})
{
$ifCounter++;
}
else
{
$ignoreIfCounter++;
}
}
sub ComIfTex {
local($cmd, $args) = @_;
$ignoreIfCounter++;
}
sub ComIfInfo {
local($cmd, $args) = @_;
$ifCounter++;
}
sub ComEnumerate {
local($cmd, $args) = @_;
push (@listStack, [$listType, $listItemPrefix, $listItemIndex]);
$listType = $numberedList;
$listItemPrefix = $args;
$listItemPrefix = 1 if $args eq "";
$listItemIndex = 0;
output ("#Indent +4\n");
}
sub ComItemize {
local($cmd, $args) = @_;
push (@listStack, [$listType, $listItemPrefix, $listItemIndex]);
$listType = $normalList;
$listItemPrefix = $args;
$listItemIndex = 0;
output ("#Indent +4\n");
}
sub ComTable {
local($cmd, $args) = @_;
push (@listStack, [$listType, $listItemPrefix, $listItemIndex]);
$listType = $tableList;
$listItemPrefix = $args;
if ($cmd eq "ftable")
{
$listItemIndex = \$FunctionIndex;
}
elsif ($cmd eq "vtable")
{
$listItemIndex = \$VariableIndex;
}
else
{
$listItemIndex = 0;
}
output ("#Indent +4\n");
}
sub ComItem {
local($cmd, $args) = @_;
# output ("\n") if $cmd eq "item";
if ($listType == $numberedList)
{
output(" $listItemPrefix. ");
$listItemPrefix++;
}
elsif ($listType == $tableList)
{
if ($listItemPrefix =~ /^{/)
{
output("#Indent\n".$listItemPrefix.$args."{f}\n#Indent +4\n");
}
else
{
output("#Indent\n$listItemPrefix$args\n#Indent +4\n");
}
IndexInsert($listItemIndex, $args) if $listItemIndex;
}
else
{
output("\n $listItemPrefix ");
}
}
sub IndexInsert {
($i, $a) = @_;
$a = RemoveAttributes($a);
$$i->{$a} = $currentFile if ! $$i->{$a};
}
sub ComExample {
local($cmd, $args) = @_;
output ("#Wrap off\n#fCode\n");
}
sub ComDisplay {
local($cmd, $args) = @_;
output ("#Wrap off\n");
}
sub ComIgnore {
local($cmd, $args) = @_;
$ignoreIt = 1;
}
sub ComC {
local($cmd, $args) = @_;
output ("# $args\n");
}
sub ComIndex {
local($cmd, $args) = @_;
local($hash);
if (!($hash = $IndexCommands{$cmd}))
{
warn "Unknown index command: $cmd\n";
return;
}
# warn "Index: $cmd $args\n";
$hash = $$hash;
$args = RemoveAttributes(rebuild($args));
$hash->{$args} = $currentFile if ! $hash->{$args};
}
sub ComSynindex {
local($cmd, $args) = @_;
local($fromhash, $tohash, $_, $1, $2);
$_ = $args;
if (! /^\s*(\w+)\s+(\w+)\s*$/)
{
warn "Wrong syncodeindex-syntax: $args\n";
return;
}
$fromhash = $IndexRefs{$1};
$tohash = $IndexRefs{$2};
if (!($fromhash && $tohash))
{
warn "Unknown index commands: >$1< >$2<\n";
return;
}
$$fromhash = $$tohash;
}
sub ComPrintindex {
local($cmd, $args) = @_;
local($_, $hash);
if (!($hash = $IndexRefs{$args}))
{
warn "Index %args unknown!\n";
return;
}
$hash = $$hash;
output ("#Wrap off\n");
for (sort(keys %$hash))
{
output(MakeRef($_,$hash->{$_})."\n");
}
output ("#Wrap on\n");
}
sub ComOneline {
local($cmd, $args) = @_;
output ($Oneline{$cmd}.$args."{f}\n");
}
sub ComPage {
local($cmd, $args) = @_;
output ("#Line\n");
}
sub ComNode {
local($cmd, $args) = @_;
local($panel, $holdPrev);
local(@par);
@par = split(/\s*,\s*/, $args);
if ($currentFile)
{
$nextNode = $par[0] if $nextNode eq "";
$ThisNode[1] = "Previous: <".$prevNode."=>".Ref2File($prevNode)."> * "
if $prevNode ne "";
$ThisNode[1] .= "Next: <".$nextNode."=>".Ref2File($nextNode)."> * "
if $nextNode ne "";
$ThisNode[1] .= "Up: <".$upNode."=>".Ref2File($upNode).">"
if $upNode ne "";
$ThisNode[1] .= "\n\n";
open(OUT, ">".$ARGV[1].$dirSep.$currentFile)
|| die "Couldn't open $currentFile!\n";
print OUT @ThisNode;
if ($noOfFootnotes)
{
print OUT "#Line\n";
print OUT @Footnotes;
}
close OUT;
}
$holdPrev = $currentNode;
($currentNode, $nextNode, $prevNode, $upNode) = @par;
$prevNode = $holdPrev if $prevNode eq "";
$upNode = $Node2Menu{$currentNode} if $upNode eq "";
@ThisNode = ("$currentNode\n", "", "#Wrap on\n");
$currentFile = Ref2File($currentNode);
$noOfFootnotes = 0;
@Footnotes = ();
}
sub ComSetTitle {
local($cmd, $args) = @_;
# tja, ne Node halt...
}
sub ComSetFileName {
local($cmd, $args) = @_;
# tja, ne Node halt...
}
sub DummyProc {
local($cmd, $args) = @_;
# warn "Warning: $cmd not supported!!\n";
}
sub ComEmph {
local($cmd, $args) = @_;
output ("\n{fEmphasis} $args {f}\n");
}
sub ComCentre {
local($cmd, $args) = @_;
output ("#Align Centre\n$args\n#Align\n");
}
sub ComFlushleft {
local($cmd, $args) = @_;
output ("#Align left\n");
}
sub ComFlushright {
local($cmd, $args) = @_;
output ("#Align right\n");
}
sub ComMenu {
local($cmd, $args) = @_;
$MenuFlag = 1;
output ("#Wrap off\n");
}
sub ComDeftypefn {
local($cmd, $_) = @_;
local(@a, $c, $t, $n);
($c, $t, $n, @a) = ParseArgs($_, 3);
output(ucfirst($c).": $t $n @a\n#Indent +4\n");
IndexInsert(\$FunctionIndex, $n);
}
sub ComDeftypefun {
local($cmd, $_) = @_;
local(@a, $c, $t);
($t, $n, @a) = ParseArgs($_, 2);
output("Function: $t $n @a\n#Indent +4\n");
IndexInsert(\$FunctionIndex, $n);
}
sub ComDeftypevar {
local($cmd, $_) = @_;
local(@a);
($t, $n, @a) = ParseArgs($_, 2);
output("Variable: $t $n @a\n#Indent +4\n");
IndexInsert(\$VariableIndex, $n);
}
sub ComDefop {
local($cmd, $_) = @_;
local(@a, $c, $t, $n);
($c, $t, $n, @a) = ParseArgs($_, 3);
output(ucfirst($c).": $t::$n @a\n#Indent +4\n");
IndexInsert(\$FunctionIndex, $n." on ".$t);
}
sub ParseArgs {
local($line, $i) = @_;
local(@a, $1, $2);
@a = ();
$2 = "";
while ($line ne "" && ($line =~ /^\s*{([^{}]*)}(.*)$/ ||
$line =~ /^\s*(\S+) (.*)$/ ||
$line =~ /^\s*(\S+)$/) && $i > 0)
{
push (@a, $1);
$line = $2;
$2 = "";
$i--;
}
return (@a, $line);
}
sub ComEnd {
local($cmd,$args) = @_;
if (grep(/^$args$/, @ifs))
{
$ifCounter--;
}
elsif ($args eq "itemize" || $args eq "enumerate" ||
$args eq "table" || $args eq "ftable" || $args eq "vtable")
{
($listType, $listItemPrefix, $listItemIndex) = @{pop(@listStack)};
output ("\n#Indent\n");
}
elsif ($args eq "example" || $args eq "smallexample" ||
$args eq "lisp" || $args eq "smalllisp")
{
output ("#f\n#Wrap on\n");
}
elsif ($args eq "menu")
{
$MenuFlag = 0;
output ("#Wrap on\n");
}
elsif ($args eq "display" ||$args eq "format")
{
output ("#Wrap on\n");
}
elsif ($args eq "flushleft" ||$args eq "flushright")
{
output ("#Align\n");
}
elsif ($args eq "quotation")
{
output ("#f\n");
}
elsif ($args eq "deftypefn" || $args eq "deftypefun" ||
$args eq "deftypevar" || $args eq "defop")
{
output ("#Indent\n");
}
elsif ($args eq "group" || $args eq "cartouche")
{
# don't care
}
else
{
warn "Unknown end sequence: $args\n";
}
}
sub ComInclude {
local($cmd,$args) = @_;
local(@help);
$args =~ s/\./\//g if $RiscOS;
open (HANDLE, $args) || die "Can't open $args\n";
@help = <HANDLE>;
close HANDLE;
@Dokument = (@help, @Dokument);
}
sub ComXRef {
local ($cmd, $_) = @_;
local ($node, $cross, $topic, $text, @args);
s/\n/ /g;
($node, $cross, $text) = split(/\s*,\s*/, $_);
$cross = $node if $cross eq "";
$text = ": $text" if $text ne "";
# warn "Converted: $_ -> <$label=>$file>";
$node = Ref2File($node);
$cross = RemoveInternalAttributes($cross);
return "\\*Note <$cross=>$node>$text";
}
sub ComSpace {
local($cmd, $args) = @_;
for (1 .. $args)
{
output ("\n");
}
}
sub RemoveInternalAttributes {
local($_) = @_;
s/$;$O/\\{/g;
s/$;$C/\\}/g;
s/$O[^$O$C]*$C//g;
s/\\{/$;$O/g;
s/\\}/$;$C/g;
return $_;
}
sub RemoveAttributes {
local($_) = @_;
s/\\{/$;$O/g;
s/\\}/$;$C/g;
s/{[^{}]*}//g;
s/$;$O/\\{/g;
s/$;$C/\\}/g;
return $_;
}
sub translateNode {
local ($_) = @_;
s/[\W]//g;
return (substr($_, 0, 10));
}
sub MakeRef {
local ($ref, $node) = @_;
if ($ref =~ /^[$refQuote]/)
{
return "<\\".$ref."=>".$node.">";
}
else
{
return "<".$ref."=>".$node.">";
}
}
sub Ref2File {
local ($_) = @_;
local ($f);
# s/{[^}]*}//g;
if ( $Node2File{$_} ne "")
{
return $Node2File{$_};
}
else
{
$f = translateNode($_);
$f = "A" if $f eq "";
while ($File2Node{$f})
{
$f++;
}
$File2Node{$f} = $_;
$Node2File{$_} = $f;
# warn "translated: $_ -> $f\n";
return $f;
}
}
sub output {
local($line) = @_;
push @ThisNode, $line;
}